package com.jetpackframework.http;


import android.util.Log;

import androidx.lifecycle.Lifecycle;

import com.blankj.utilcode.util.GsonUtils;
import com.google.gson.Gson;
import com.jetpackframework.retrofit.ResponseBodyConverter;
import com.jetpackframework.retrofit.converter.GsonResponseBodyConverter;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import okhttp3.Call;
import okhttp3.Response;

public class CallBack<T> extends com.zhy.http.okhttp.callback.Callback<T> implements okhttp3.Callback {

    private HttpTask<T> httpParams;

    public CallBack(HttpTask<T> httpParams) {
        this.httpParams = httpParams;
    }

    @Override
    public void onFailure(Call call, IOException e) {
        if (httpParams.getObserver() != null){
            httpParams.getObserver().onError(e,0);
        }
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        synchronized (CallBack.class) {
            httpParams.getObserver().onHeader(response.headers());
            if (httpParams.getLifecycle().getCurrentState() == Lifecycle.State.STARTED || httpParams.getLifecycle().getCurrentState() == Lifecycle.State.RESUMED || httpParams.getLifecycle().getCurrentState() == Lifecycle.State.CREATED) {
                T t = parseNetworkResponse(response, 0);
                if (!httpParams.isStream()) {
                    onResponse(t, 0);
                }
            }else {
                Log.e(getClass().getSimpleName(),"task url:"+httpParams.getUrl()+" lifecycle expired!");
            }
        }
    }

    @Override
    public T parseNetworkResponse(Response response, int id) throws IOException {
        if (HttpUtil.getInstance().responseConverter.isEmpty()){
            HttpUtil.getInstance().addResponseConverter(new GsonResponseBodyConverter(GsonUtils.getGson()));
        }
        synchronized (CallBack.class) {
            if (!httpParams.isStream()) {
                for (ResponseBodyConverter converter : HttpUtil.getInstance().responseConverter) {
                    converter.setClass(httpParams.getResult());
                    return (T) converter.convert(response);
                }
            }else {
                saveFile(response,httpParams.getStreamPath());
            }
        }
        return null;
    }

    @Override
    public void onError(Call call, Exception e, int id) {
        if (httpParams.getObserver() != null){
            httpParams.getObserver().onError(e,0);
        }
    }

    @Override
    public void onResponse(T response, int id) {
        if (httpParams.getObserver() != null) {
            httpParams.getObserver().onNext(response, id);
        }
    }
    private void saveFile(Response response, String streamPath) {
        InputStream inputStream = response.body().byteStream();
        File file = new File(streamPath);
        if (!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(streamPath));
            byte[] buffer = new byte[1024];
            int length = 0;
            while ((length = inputStream.read(buffer)) != -1){
                bos.write(buffer,0,length);
                bos.flush();
            }
            bos.flush();

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (httpParams.getObserver() != null ){
                httpParams.getObserver().onNext((T) file.getAbsolutePath(),0);
            }
            if (bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}
